home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / CBGRX100.ARJ / FONTCVT.C < prev    next >
Text File  |  1992-01-10  |  9KB  |  392 lines

  1. /*
  2.  * cvtfont.c
  3.  */
  4.  
  5. #include "grx.h"
  6. #include "grxfile.h"
  7. #include <stdio.h>
  8. #include <string.h>
  9. #include <ctype.h>
  10. #include <stdlib.h>
  11.  
  12. short *width_table = NULL;
  13. char  **bitmap = NULL;
  14. char  *workline = NULL;
  15. char  name[100];
  16. char  family[100];
  17. long  bitmapsize;
  18. int   inwidth;
  19. int   inheight;
  20. int   outwidth;
  21. int   outheight;
  22. int   xpad1 = 0;
  23. int   xpad2 = 0;
  24. int   ypad1 = 0;
  25. int   ypad2 = 0;
  26. int   minchar;
  27. int   maxchar;
  28. int   isfixed;
  29. int   numchars;
  30. int   verbose;
  31. int   wantfixed;
  32. int   center_h = 0;
  33. int   center_w = 0;
  34.  
  35. FILE *infile;
  36. FILE *outfile;
  37.  
  38. #define ASC2BIN      0
  39. #define BIN2ASC      1
  40. #define MAKEDIR      2
  41.  
  42. int make_bitmap(int w,int h)
  43. {
  44.     static int  last_w = -1;
  45.     static int  last_h = -1;
  46.     char *area = NULL;
  47.     int  ii;
  48.  
  49.     if((w <= last_w) && (h <= last_h)) return(1);
  50.     if(workline != NULL) free(workline);
  51.     if(bitmap != NULL) free(bitmap);
  52.     bitmap = malloc(sizeof(char *) * h);
  53.     area = malloc(w * (h + 1));
  54.     if((bitmap == NULL) || (area == NULL)) return(0);
  55.     workline = area;
  56.     for(ii = 0; ii < h; ii++) bitmap[ii] = (area += w);
  57.     last_w = w;
  58.     last_h = h;
  59.     return(1);
  60. }
  61.  
  62. char *getline(char *buff)
  63. {
  64.     char *p = buff;
  65.     int  chr;
  66.  
  67.     while((chr = getc(infile)) != EOF) {
  68.         if(chr == '\n') {
  69.         *p = '\0';
  70.         if((buff[0] == '\0') || (buff[0] == ';')) {
  71.             p = buff;
  72.             continue;
  73.         }
  74.         return(buff);
  75.         }
  76.         *p++ = chr;
  77.     }
  78.     return(NULL);
  79. }
  80.  
  81. int read_header(void)
  82. {
  83.     char *p;
  84.     char param[100],value[100],lnbuff[200];
  85.     int  have_params = 0;
  86.  
  87.     while(have_params < 5) {
  88.         if((p = getline(lnbuff)) == NULL) return(0);
  89.         if(sscanf(p,"%s %s",param,value) < 2) return(0);
  90.         if(strcmp(param,"family") == 0)
  91.         strcpy(family,value);
  92.         else if(strcmp(param,"width") == 0)
  93.         inwidth = atoi(value);
  94.         else if(strcmp(param,"height") == 0)
  95.         inheight = atoi(value);
  96.         else if(strcmp(param,"minchar") == 0)
  97.         minchar = atoi(value);
  98.         else if(strcmp(param,"maxchar") == 0)
  99.         maxchar = atoi(value);
  100.         else return(0);
  101.         have_params++;
  102.     }
  103.     return(1);
  104. }
  105.  
  106. void write_header(void)
  107. {
  108.     FntFileHdr fhdr;
  109.  
  110.     memset(&fhdr,0,sizeof(fhdr));
  111.     fhdr.magic = FONT_MAGIC;
  112.     fhdr.bitmapsize = bitmapsize;
  113.     fhdr.h.fnt_isfixed  = isfixed;
  114.     fhdr.h.fnt_width    = inwidth;
  115.     fhdr.h.fnt_height   = inheight;
  116.     fhdr.h.fnt_minchar  = minchar;
  117.     fhdr.h.fnt_maxchar  = maxchar;
  118.     fhdr.h.fnt_internal = 0;
  119.     strncpy(fhdr.h.fnt_name,name,GR_NAMEWIDTH);
  120.     strncpy(fhdr.h.fnt_family,family,GR_NAMEWIDTH);
  121.     fhdr.h.fnt_name[GR_NAMEWIDTH - 1] = '\0';
  122.     fhdr.h.fnt_family[GR_NAMEWIDTH - 1] = '\0';
  123.     fwrite(&fhdr,sizeof(fhdr),1,outfile);
  124. }
  125.  
  126. void write_table(void)
  127. {
  128.     fwrite(width_table,sizeof(short),numchars,outfile);
  129. }
  130.  
  131. int read_asciimap(void)
  132. {
  133.     int ii,jj;
  134.     char *p,lnbuff[200];
  135.  
  136.     for(ii = 0; ii < inheight; ii++) {
  137.         if((p = getline(lnbuff)) == NULL) return(0);
  138.         for(jj = 0; jj < inwidth; jj++) {
  139.         switch(*p++) {
  140.             case '#': bitmap[ii][jj] = 1; break;
  141.             case '.': bitmap[ii][jj] = 0; break;
  142.             default:  return(0);
  143.         }
  144.         }
  145.     }
  146.     return(1);
  147. }
  148.  
  149. void center_width(void)
  150. {
  151.     int fmin,fmax;
  152.     int offs,copy;
  153.     int ii,jj;
  154.  
  155.     fmax = 0;
  156.     fmin = outwidth;
  157.     for(ii = 0; ii < outheight; ii++) {
  158.         for(jj = 0; jj < outwidth; jj++) {
  159.         if(bitmap[ii][jj]) {
  160.             if(fmax < jj) fmax = jj;
  161.             if(fmin > jj) fmin = jj;
  162.         }
  163.         }
  164.     }
  165.     copy = fmax - fmin + 1;
  166.     if(copy <= 0) return;
  167.     offs = (outwidth - copy) / 2;
  168.     for(ii = 0; ii < outheight; ii++) {
  169.         memset(workline,0,outwidth);
  170.         memcpy(&workline[offs],&bitmap[ii][fmin],copy);
  171.         memcpy(bitmap[ii],workline,outwidth);
  172.     }
  173. }
  174.  
  175.  
  176. void transform_bitmap(void)
  177. {
  178. /*    if(outwidth  != inwidth)  pad_width();
  179.     if(outheight != inheight) pad_height();  */
  180.     if(center_w) center_width();
  181. }
  182.  
  183. int write_bitmap(void)
  184. {
  185.     int  ii,jj,kk,wdt;
  186.     int  bits,mask;
  187.  
  188.     for(ii = 0; ii < numchars; ii++) {
  189.         if(!read_asciimap()) return(0);
  190.         transform_bitmap();
  191.         wdt = isfixed ? outwidth : width_table[ii];
  192.         for(jj = 0; jj < outheight; jj++) {
  193.         bits = 0;
  194.         mask = 0x100;
  195.         for(kk = 0; kk < wdt; kk++) {
  196.             if((mask >>= 1) == 0) {
  197.             putc(bits,outfile);
  198.             bits = 0;
  199.             mask = 0x80;
  200.             }
  201.             if(bitmap[jj][kk]) bits |= mask;
  202.         }
  203.         putc(bits,outfile);
  204.         }
  205.     }
  206.     return(1);
  207. }
  208.  
  209. int convert_font(char *inname)
  210. {
  211.     char outname[200];
  212.     char *p;
  213.  
  214.     if((infile = fopen(inname,"r")) == NULL) {
  215.         fprintf(stderr,"error opening input file: %s\n",inname);
  216.         return(0);
  217.     }
  218.     if(!read_header()) {
  219.         fprintf(stderr,"invalid input file: %s\n",inname);
  220.         fclose(infile);
  221.         return(0);
  222.     }
  223.     if(!make_bitmap(inwidth,inheight)) {
  224.         fprintf(stderr,"insufficient memory\n");
  225.         fclose(infile);
  226.         exit(1);
  227.     }
  228.     outwidth   = inwidth;
  229.     outheight  = inheight;
  230.     numchars   = maxchar - minchar + 1;
  231.     bitmapsize =
  232.         (long)numchars * (long)(((outwidth + 7) >> 3) * outheight);
  233.     strcpy(outname,inname);
  234.     p = strrchr(outname,'.');
  235.     if(p != NULL) *p = '\0';
  236.     strcat(outname,".fnt");
  237.     if((outfile = fopen(outname,"wb")) == NULL) {
  238.         fprintf(stderr,"error creating output file: %s\n",outname);
  239.         fclose(infile);
  240.         return(0);
  241.     }
  242.     if(verbose) printf("  converting font: %s to %s\n",inname,outname);
  243.     p = strrchr(outname,'\\');
  244.     if(p == NULL) p = strrchr(outname,'/');
  245.     if(p == NULL) p = strrchr(outname,':');
  246.     if(p == NULL) p = outname;
  247.     strcpy(name,outname);
  248.     for(p = name; *p != '\0'; p++) *p = tolower(*p);
  249.     write_header();
  250.     if(!write_bitmap()) {
  251.         fprintf(stderr,"error reading input file: %s\n",inname);
  252.         fclose(infile);
  253.         fclose(outfile);
  254.         unlink(outname);
  255.         return(0);
  256.     }
  257.     fclose(infile);
  258.     if(ferror(outfile)) {
  259.         fprintf(stderr,"error writing output file: %s\n",outname);
  260.         fclose(outfile);
  261.         unlink(outname);
  262.         return(0);
  263.     }
  264.     fclose(outfile);
  265.     return(1);
  266. }
  267.  
  268. int createdir(char *name,int numfonts)
  269. {
  270.     FntDirHdr hdr;
  271.  
  272.     if((outfile = fopen(name,"wb")) == NULL) {
  273.         fprintf(stderr,"error creating directory file: %s\n",name);
  274.         return(0);
  275.     }
  276.     if(verbose) printf("creating font directory: %s\n",name);
  277.     hdr.magic = FONTDIR_MAGIC;
  278.     hdr.numentries = numfonts;
  279.     fwrite(&hdr,sizeof(hdr),1,outfile);
  280.     return(1);
  281. }
  282.  
  283. int addentry(char *name)
  284. {
  285.     FntFileHdr fhdr;
  286.  
  287.     if((infile = fopen(name,"rb")) == NULL) {
  288.         fprintf(stderr,"error opening input file: %s\n",name);
  289.         return(0);
  290.     }
  291.     if((fread(&fhdr,sizeof(fhdr),1,infile) != 1) ||
  292.        (fhdr.magic != FONT_MAGIC)) {
  293.         fprintf(stderr,"invalid input file: %s\n",name);
  294.         return(0);
  295.     }
  296.     if(verbose) printf("  adding font: %s\n",name);
  297.     fwrite(&fhdr.h,sizeof(GrFont),1,outfile);
  298.     fclose(infile);
  299.     return(1);
  300. }
  301.  
  302. void usage(void)
  303. {
  304.     fprintf(stderr,"usage: fontdisp [<options>] font [-o output] ...\n");
  305.     exit(1);
  306. }
  307.  
  308. void main(int argc,char **argv)
  309. {
  310.     int  ii;
  311.     char *p;
  312.     char **fonts,**fp;
  313.     char **result,**rp;
  314.     char *dirname;
  315.     int  numfonts;
  316.     int  operation;
  317.  
  318.     isfixed      = 1;
  319.     verbose      = 0;
  320.     wantfixed = 1;
  321.     operation = ASC2BIN;
  322.     fonts  = malloc(sizeof(char *) * (argc + 1));
  323.     result = malloc(sizeof(char *) * (argc + 1));
  324.     if((fonts == NULL) || (result == NULL)) {
  325.         fprintf(stderr,"insufficient memory\n");
  326.         exit(1);
  327.     }
  328.     numfonts = 0;
  329.     fp = fonts;
  330.     rp = result;
  331.     for(ii = 1; ii < argc; ii++) {
  332.         if(*(p = argv[ii]) == '-') {
  333.         if(strcmp(p,"-v") == 0)
  334.             verbose = 1;
  335.         else if(strcmp(p,"-u") == 0)
  336.             operation = BIN2ASC;
  337.         else if(strcmp(p,"-cw") == 0)
  338.             center_w = 1;
  339.         else if(strcmp(p,"-ch") == 0)
  340.             center_h = 1;
  341.         else if(strcmp(p,"-d") == 0) {
  342.             operation = MAKEDIR;
  343.             dirname = "fonts.dir";
  344.         }
  345.         else if(strncmp(p,"-do",3) == 0) {
  346.             operation = MAKEDIR;
  347.             if(p[3] != '\0') p += 3;
  348.             else if(++ii == argc) usage();
  349.             else p = argv[ii];
  350.             dirname = p;
  351.         }
  352.         else if(strncmp(p,"-o",2) == 0) {
  353.             if(rp == result) usage();
  354.             if(p[2] != '\0') p += 2;
  355.             else if(++ii == argc) usage();
  356.             else p = argv[ii];
  357.             rp[-1] = p;
  358.         }
  359.         else usage();
  360.         }
  361.         else {
  362.         *fp++ = p;
  363.         *rp++ = NULL;
  364.         numfonts++;
  365.         }
  366.     }
  367.     switch(operation) {
  368.       case ASC2BIN:
  369.         for(ii = 0; ii < numfonts; ii++)
  370.         if(!convert_font(fonts[ii])) exit(1);
  371.         break;
  372.       case MAKEDIR:
  373.         if(!createdir(dirname,numfonts)) exit(1);
  374.         for(ii = 0; ii < numfonts; ii++) {
  375.         if(!addentry(fonts[ii])) {
  376.             fclose(outfile);
  377.             unlink(dirname);
  378.             exit(1);
  379.         }
  380.         }
  381.         if(ferror(outfile)) {
  382.         fprintf(stderr,"error writing directory file: %s\n",dirname);
  383.         fclose(outfile);
  384.         unlink(dirname);
  385.         exit(1);
  386.         }
  387.         break;
  388.     }
  389.     exit(0);
  390. }
  391.  
  392.